package com.ad.common.utils;

import java.io.*;
import java.util.Iterator;
import java.util.List;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.DocumentException;
import org.dom4j.io.*;
import java.util.Hashtable;

public class Dom4JUtils {

	public Dom4JUtils() {
	}

	public static Hashtable explainXml(String xmlStr) {
		Hashtable hashtable = new Hashtable();
		Document document = buildFromXMLString(xmlStr);
		Element element = document.getRootElement();
		Iterator it = element.elementIterator();
		Element el;
		while (it.hasNext()) {
			el = (Element) it.next();
			hashtable.put(el.getName(), el.getStringValue());
		}

		return hashtable;
	}

	public static String StringXmlValue(String xmlStr, String elementName) {
		String value = null;
		Document document = buildFromXMLString(xmlStr);
		Element element = document.getRootElement();
		Element findElement = findElement(element, elementName);
		value = findElement == null ? null : findElement.getTextTrim();
		return value;
	}

	public static Document buildFromFile(String filePath) {
		Document doc = null;
		try {
			SAXReader reader = new SAXReader();
			doc = reader.read(new File(filePath));
		} catch (DocumentException e) {
			e.printStackTrace();
		} catch (NullPointerException e) {
			e.printStackTrace();
		}
		return doc;
	}

	public static Document buildFromXMLString(String xmlString) {
		Document doc = null;
		try {
			SAXReader reader = new SAXReader();
			doc = reader.read(new StringReader(xmlString));
		} catch (DocumentException e) {
			e.printStackTrace();
		} catch (NullPointerException e) {
			e.printStackTrace();
		}
		return doc;
	}

	public static Document buildFromDom(org.w3c.dom.Document document) {
		DOMReader reader = new DOMReader();
		Document doc = reader.read(document);
		return doc;
	}

	public static void outputToStdout(Document doc) {
		outputToStdout(doc, "UTF-8");
	}

	public static void outputToStdout(Document doc, String encoding) {
		OutputFormat format = new OutputFormat("\t", true, encoding);
		try {
			XMLWriter xmlwriter = new XMLWriter(System.out, format);
			xmlwriter.write(doc);
			xmlwriter.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static String outputToString(Document document) {
		return outputToString(document, "UTF-8");
	}

	public static String outputToString(Document document, String encoding) {
		OutputFormat format = new OutputFormat("\t", true, encoding);
		ByteArrayOutputStream byteRep = new ByteArrayOutputStream();
		try {
			XMLWriter xmlwriter = new XMLWriter(byteRep, format);
			xmlwriter.write(document);
			xmlwriter.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		String tmp = byteRep.toString();
		return tmp;
	}

	public static org.w3c.dom.Document outputToDom(Document document) {
		DOMWriter domWriter = new DOMWriter();
		org.w3c.dom.Document doc = null;
		try {
			doc = domWriter.write(document);
		} catch (DocumentException e) {
			e.printStackTrace();
		}
		return doc;
	}

	public static void outputToFile(Document myDocument, String filePath) {
		outputToFile(myDocument, filePath, "UTF-8");
	}

	public static void outputToFile(Document document, String filePath,
			String encoding) {
		OutputFormat format = new OutputFormat("\t", true, encoding);
		try {
			FileWriter writer = new FileWriter(filePath);
			XMLWriter xmlwriter = new XMLWriter(writer, format);
			xmlwriter.write(document);
			xmlwriter.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void executeXSL(Document document, String xslFilePath,
			StreamResult xmlResult) {
		try {
			TransformerFactory tFactory = TransformerFactory.newInstance();
			DOMWriter domWriter = new DOMWriter();
			org.w3c.dom.Document doc = domWriter.write(document);
			javax.xml.transform.Source xmlSource = new DOMSource(doc);
			StreamSource xsltSource = new StreamSource(new FileInputStream(
					xslFilePath));
			Transformer transformer = tFactory.newTransformer(xsltSource);
			transformer.transform(xmlSource, xmlResult);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (TransformerConfigurationException e) {
			e.printStackTrace();
		} catch (TransformerException e) {
			e.printStackTrace();
		} catch (DocumentException e) {
			e.printStackTrace();
		}
	}

	public static Element findElement(Element node, String elementName) {
		Element element = null;
		if (node == null)
			return null;
		if (node.getName().equals(elementName)) {
			element = node;
		} else {
			List child = node.elements();
			if (!child.isEmpty()) {
				Element selectedNode = null;
				for (int i = 0; i < child.size(); i++) {
					selectedNode = (Element) child.get(i);
					if (selectedNode.getName().equals(elementName)) {
						element = selectedNode;
						break;
					} else {
						selectedNode = findElement(selectedNode, elementName);
						if (selectedNode != null) {
							element = selectedNode;
						}
					}
				}
			}
		}
		return element;
	}
}
